
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <stdio.h>
#include <sys/time.h>
#include <vector>
#include "app_platform/cntl_info.h"
#include "app_platform/cgi_stub_cntl.h"

#include "c2cent/library/log/CWTimeElf3.h"
#include "c2cplatform/library/string/string_helper.h"
#include "c2cplatform/library/the3/tconv/tconv_g2u.h"

#include "libc2c/c2c_errno_define.h"
#include "erp/dms/po/shiptypefilterpo_dms.h"
#include "erp/dms/po/shiptypeareapo_dms.h"
#include "erp/gis/comm/erp_gis_define.h"

#include "erp/gis/ao/giscoreao_stub4web_allinone.h"
#include "b2b2c/icson_recvaddr/ao/icsonrecvaddressao_stub4web_allinone.h"
#include "b2b2c/address_mapping/ao/addressmappingao_stub4web_allinone.h"

using std::map;
using std::string;
using std::stringstream;
using std::cout;
using std::endl;
using std::vector;
using namespace c2cent::library::wwlog;
using namespace c2cent::library::wtimeelf;
using namespace c2cplatform::library::string;

using namespace erp::gis::comm;
using namespace b2b2c::address_mapping::po;
using namespace b2b2c::address_mapping::ao;

enum _ARGV_INDEX{
    INDEX_UID = 0,

    ARGV_INDEX_MAX,
};

void Init()
{       
	if(CCGI_STUB_CNTL->Initialize(true) != 0)
		cout << "CCGI_STUB_CNTL->Init failed" << endl;
	CCGI_STUB_CNTL->setTimeout(5);

	uint32_t g_dwIsCanLogRemote = 0;
	uint32_t g_dwLogSwitch = WLOG_ALL_OPEN;
	int iRetCode = C2C_WWLOG->QuickInitForAPP2("ToolUserAddrCoordinate",
				C2CWW_LOG_APP_FILE_PATH, g_dwIsCanLogRemote, g_dwLogSwitch);
	if (iRetCode)
	{
		cout << "C2C_WWLOG Init Fail, iRetCode:" << iRetCode << endl;
	}
}

inline string GbkToUtf8(const std::string& srtGbk)
{
	string strUtf8 = "";
	char szBuf[1024];
	size_t dwLen = srtGbk.length()*2;
	int iErrNum = tconv_gbk2utf8(srtGbk.c_str(), srtGbk.length(), szBuf, &dwLen);
	if(iErrNum == 0)
		strUtf8 = szBuf;
	else
		strUtf8 = srtGbk;

	return strUtf8;
}

bool SortByTime(const b2b2c::icson_recvaddr::po::CIcsonRecvAddrPo& oAddr1,
			const b2b2c::icson_recvaddr::po::CIcsonRecvAddrPo& oAddr2)
{
	bool bResult = false;
	if(oAddr1.GetLastUseTime() > oAddr2.GetLastUseTime())
	{
		bResult = true;
	}else if (oAddr1.GetLastUseTime() < oAddr2.GetLastUseTime())
	{
		bResult = false;
	}else
	{
		bResult = (oAddr1.GetUpdateTime() > oAddr2.GetUpdateTime());
	}

	return bResult;
}

uint32_t GetUserAddrCoordinate(vector<string>& vecInput)
{
	uint32_t dwRet = 0;

	cout << "Uid:[" << vecInput[INDEX_UID] << "]" << endl;
	uint64_t ddwUid = atol(vecInput[INDEX_UID].c_str());
	if(ddwUid == 0)
		return dwRet;

	CCntlInfo oCntlInfo;
	oCntlInfo.setOperatorUin(ddwUid);
	oCntlInfo.setRouteKey(ddwUid);
	const std::string strMachineKey = __FILE__;
	const std::string strSource = __FUNCTION__;
	uint32_t dwSceneId = 0;
	std::string strInReserve = "", strErrMsg = "", strOutReserve = "";

    //查询用户的常用地址列表
    b2b2c::icson_recvaddr::po::CIcsonRecvAddrPoList oRecvAddrList;
    b2b2c::icson_recvaddr::ao::CIcsonRecvAddressAoStub4Web oAddrStub;
    dwRet = oAddrStub.GetIcsonRecvAddr(oCntlInfo, strMachineKey, strSource,
    				dwSceneId, ddwUid, strInReserve,
    				oRecvAddrList, strErrMsg, strOutReserve);
    vector<b2b2c::icson_recvaddr::po::CIcsonRecvAddrPo>& vecRecvAddr =
    				oRecvAddrList.GetIcsonRecvAddrPoList();
    if(dwRet || vecRecvAddr.size() == 0)
    {
    	printf("[%u] GetIcsonRecvAddr Fail Or AddrList Is Empty, ErrMsg[%s][%s] Uid[%lu] AddrList.size[%u] \n",
    			dwRet, strErrMsg.c_str(), oAddrStub.GetLastErrMsg(), ddwUid, (uint32_t)vecRecvAddr.size());

		return dwRet;
    }
    printf("GetIcsonRecvAddr Done, Uid[%lu] AddrList.size[%u] \n", ddwUid, (uint32_t)vecRecvAddr.size());

    //对收货地址按使用时间和更新时间排序，
	sort(vecRecvAddr.begin(), vecRecvAddr.end(), SortByTime);

	//调用AoGisCore.GetMergeCoordinate，刷新用户收货地址的经纬度
	erp::gis::po::CMergedCoordinatesPo coordPo;
 	erp::gis::ao::CGisCoreAoStub4Web oGisStub;

 	printf("Start GisAo.GetMergeCoordinate .....\n");
 	//查前10个
 	uint32_t dwCoorUpdateCnt = 0;
 	uint32_t dwRefreshMax = 10, dwCnt = 0;
 	for(vector<b2b2c::icson_recvaddr::po::CIcsonRecvAddrPo>::iterator itRecvAddr = vecRecvAddr.begin();
 			itRecvAddr != vecRecvAddr.end() && dwCnt < dwRefreshMax; ++itRecvAddr, ++dwCnt)
 	{
 		//用收货地址的易标ID，查对应国标的省市区名称
 		map<uint32_t, uint32_t>& mapDistId = itRecvAddr->GetDistrictIdMap();
 		const uint32_t dwDestYbId = mapDistId[AREA_ID_ICSON];
 		const uint64_t ddwAddrId = itRecvAddr->GetIcsonAid();

 		b2b2c::address_mapping::po::CAreaDetailInfoPo oAreaDetailInfo;
 		b2b2c::address_mapping::ao::CAddressMappingAoStub4Web oAddrMapStub;

 		dwRet = oAddrMapStub.GetAreaInfoByGbExtId(oCntlInfo, strMachineKey, strSource,
 				dwSceneId, 0, dwDestYbId, strInReserve, oAreaDetailInfo,
 				strErrMsg, strOutReserve);
 		if(dwRet)
 		{
 			printf("[%u] GetAreaInfoByGbExtId Fail, DestYbId[%u] AddrId[%lu] Uid[%lu] ErrMsg[%s][%s] \n",
 					dwRet, dwDestYbId, ddwAddrId, ddwUid, strErrMsg.c_str(), oAddrMapStub.GetLastErrMsg());
 			continue;
 		}

 		const b2b2c::address_mapping::po::CAreaStandardInfoPo&
 						gbAreaInfo = oAreaDetailInfo.GetAreaDetailMap()[AREA_ID_GB] ;
 		const string& strProvName = gbAreaInfo.GetProvinceName();
 		const string& strCityName = gbAreaInfo.GetCityName();
 		string strDistName = gbAreaInfo.GetDistrictName();
 		string strAddrText = GbkToUtf8(itRecvAddr->GetAddress()); //gbk转utf8

 		dwRet = oGisStub.GetMergeCoordinate(oCntlInfo, strMachineKey, strSource, dwSceneId,
 									strProvName, strCityName, strDistName, strAddrText,
 									strInReserve, coordPo,strErrMsg, strOutReserve);
 		if(dwRet)
 		{
 			printf("[%u] GetMergeCoordinate Fail, ErrMsg[%s][%s] Uid[%lu]"
 					" AddrId[%lu] ProvName[%s] CityName[%s] DistName[%s] AddrText[%s] \n",
 					dwRet, strErrMsg.c_str(), oGisStub.GetLastErrMsg(), ddwUid, ddwAddrId,
 					strProvName.c_str(), strCityName.c_str(), strDistName.c_str(), strAddrText.c_str());
 			continue;
 		}else
 		{
 			printf("Id[%lu]_[%s %s %s %s]: \t[x, y][%s, %s] TrustLv[%u]\n",
 					ddwAddrId, strProvName.c_str(), strCityName.c_str(), strDistName.c_str(), strAddrText.c_str(),
 					coordPo.GetXPoint().c_str(), coordPo.GetYPoint().c_str(), coordPo.GetTrustLevel());
 		}

 		++dwCoorUpdateCnt;
	}

	printf("GetMergeCoordinate Done, Uid[%lu] AddrList.size[%u] QueryDone.Cnt[%u]\n",
		ddwUid, (uint32_t)vecRecvAddr.size(), dwCoorUpdateCnt);
	return dwRet;
}

//查看一个用户的所有地址的经纬度及信任级别信息的工具
int main(int argc, char** argv)
{
	Init();

    if(argc < 2 || (strcmp(argv[1], "-help") == 0) || (strcmp(argv[1], "-h") == 0))
	{
		cout << "======================= " << argv[0] << " v1.0 =======================" << endl;
		cout << argv[0] << " [option]" << endl;
		cout << "           gaddrc   GetUserAddrCoordinate  [output in utf8]    " << endl;
		exit(0);
	}

//    printf("option:%s\n", argv[1]);
	string strOption = argv[1];

	if(strOption == "gaddrc")
	{
//		printf("Test........GetUserAddrCoordinate\n");
		printf("USAGE    : %s gaddrc  uid \n", argv[0]);

		if(argc >= 2 + 1) //max 3
		{
			std::vector<std::string> vecInput;
			vecInput.resize(ARGV_INDEX_MAX);
			vecInput[INDEX_UID] = argv[2];

			GetUserAddrCoordinate(vecInput);
		}
	}

	return 0;
}
